/**
 *@author   wuwg
 *@createTime   2018/04/07
 *@updateTime   2018/04/11
 *@description  form-item-props public property，form-item的公用属性
 */
import config from '../config/config.js'

export default {
  props: {
    /**
     * #property
     *
     * @name    v-model
     * @cn      双向绑定
     * @group   数据
     * @type    text
     * @bind   mustnot
     * @description VUE官方指令，提供数据的双向绑定功能
     */

    /**
     * #property
     *
     * @name    prop
     * @cn      属性key
     * @group   数据
     * @type    text
     * @description 表单对象中属性的key，如有层级关系以.分隔，只有resetFields方法会使用此属性
     */
    prop: {
      type: String
    },
    /**
     * #property
     *
     * @name    label
     * @cn      标签
     * @group   标签
     * @type    text
     * @description 标签名称
     */
    label: {
      type: String
    },
    /**
     * #property
     *
     * @name    labelWidth
     * @cn      标签宽度
     * @group   标签
     * @type    numeric
     * @bind    must
     * @description  标签的宽度，单位像素
     */
    labelWidth: {
      type: Number
    },
    /**
     * #property
     *
     * @name     labelPosition
     * @cn       标签位置
     * @group   标签
     * @type    list
     * @options [left,right,top]
     * @description  表单域标签的位置，取值为 [left、right、top]中的其中一个,不选默认从form继承
     */
    labelPosition: {
      validator (value) {
        return Artery.isOneOf(value, ['left', 'right', 'top'])
      }
    },
    /**
     * #property
     *
     * @name    rules
     * @cn      验证规则
     * @group   验证
     * @type    text
     * @bind    must
     * @description 该项数据验证规则，具体配置查看   async-validator:  https://github.com/yiminghe/async-validator
     *  举例：  {required:true,message:'必填项'} || [{required:true,message:'必填项'},{type:‘number’,message:'必须为数值类型'}]
     */
    rules: {
      type: [Object, Array]
    },

    /**
     * #property
     *
     * @name    showMessage
     * @cn      是否显示校验错误信息
     * @group   验证
     * @type    boolean
     * @bind    must
     * @value    true
     * @description 是否显示校验错误信息
     */
    showMessage: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    labelFor
     * @cn      for=“elementId”
     * @group   标签
     * @type    text
     * @description label的for属性指向对应的input 或者其他的 form元素
     */
    labelFor: {
      type: String
    },
    /**
     * #property
     *
     * @name    required
     * @cn      是否必填
     * @group   验证
     * @type    boolean
     * @value  false
     * @description 是否必填，如不设置，则会根据校验规则自动生成
     */
    required: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    doValidate
     * @cn      是否校验
     * @group   验证
     * @type    boolean
     * @bind    must
     * @value  true
     * @description 是否校验，如不设置，则会根据校验规则进行校验
     */
    doValidate: {
      type: Boolean,
      default: true
    },
    /**
     * #property
     *
     * @name    forceValidate
     * @cn      是否强制校验
     * @group   验证
     * @type    boolean
     * @value   false
     * @description 是否强制校验，默认是否. 如控件隐藏也需要校验, 则设置为true
     */
    forceValidate: {
      type: Boolean,
      default: false
    },
    /**
     * #property
     *
     * @name    min
     * @cn      最小值
     * @group   验证
     * @type    text
     * @bind    must
     * @description 数据项的数值最小值，或者最小长度
     */
    min: {
      type: Number
    },
    /**
     * #property
     *
     * @name    max
     * @cn      最大值
     * @group   验证
     * @type    text
     * @bind    must
     * @description 数据项的数值最大值，或者最大长度
     */
    max: {
      type: Number
    },
    /**
     * #property
     *
     * @name    pattern
     * @cn      正则
     * @group   验证
     * @type    text
     * @description 数据项的正则验证，绑定一个RegExp对象
     */
    pattern: {
      type: null
    },
    /**
     * #property
     *
     * @name    patternMessage
     * @cn      正则验证消息
     * @group   验证
     * @type    text
     * @description 数据项的正则验证失败后的消息提示
     */
    patternMessage: {
      type: String
    },
    /**
     * #property
     *
     * @name    validator
     * @cn      函数验证
     * @group   验证
     * @type    text
     * @bind    must
     * @description 数据项的函数验证 写验证代码。最后执行回调函数，callback 传参说明验证失败，不传参说明验证成功
     *  validaor:function(rule,value,callback){
     *      callback('验证失败！')
     *  }
     */
    validator: {
      type: Function
    },
    /**
     * #property
     *
     * @name      validateOption
     * @cn        常用验证
     * @group     验证
     * @type      list
     * @options    [手机号,邮箱,一代身份证,二代身份证,中文,IP]
     * @description   常用验证，取值为 [手机号,邮箱,一代身份证,二代身份证,中文,IP,邮箱,日期格式(yyyy-MM-dd)] 中的一个,默认无
     */
    validateOption: {
      validator (value) {
        return Artery.isOneOf(value, ['手机号', '邮箱', '一代身份证', '二代身份证', '中文', 'IP'])
      }
    }
  },
  data () {
    return {
      //  是否是 form-item
      isFormItem: false
    }
  },
  computed: {
    //  获取父级form组件
    form: {
      cache: false,
      get () {
        let parent = this.$parent
        // debugger
        if (parent) {
          while (parent.$options.name !== config.prefix + '-form') {
            parent = parent.$parent
            //  如果不存在父级组件，那么退出循环
            if (!parent) {
              break
            }
          }
        }
        return parent
      }
    }
  },
  methods: {
    // 判断是否是form-item
    adjustIsFormItem () {
      if (this.label || this.labelWidth || this.required || this.rules || this.error || this.validateStatus || this.labelFor || this.form) {
        this.isFormItem = true
      }
    },
    /*
     * 初始化值
     * handleInitialValue: function () {
     *     //  如果是下拉框组件
     *     if (this.$options.name == config.prefix + '-select') {
     *         // 如果是多选
     *         if (this.multiple) {
     *             this.selectedMultiple = this.initialValue;
     *             // 单选
     *         } else {
     *             this.selectedSingle = this.initialValue
     *         }
     *         this.$emit('change', (this.multiple ? this.selectedMultiple : this.selectedSingle), this.name, this.index);
     *         //  分发事件，这里是再次初始化
     *         this.dispatchEvent('initValue', this.multiple ? this.selectedMultiple : this.selectedSingle)
     *         // 非下拉组件
     *     } else {
     *         // 当前值
     *         this.currentValue = this.initialValue;
     *         // 触发change事件
     *         this.$emit('change', this.currentValue, this.name, this.index, event);
     *         // 单选
     *         if (this.$options.name == config.prefix + '-radio-group') {
     *             //  分发事件，这里是再次初始化
     *             this.dispatchEvent('initValue', this.currentValue ? this.currentValue : null)
     *         } else {
     *             //  分发事件，这里是再次初始化
     *             this.dispatchEvent('initValue', this.currentValue)
     *         }
     *     }
     * },
     */

    // 分发事件
    dispatchEvent: function (eventType, value) {
      if (this.isFormItem) {
        var _value = (typeof value !== 'undefined') ? value : this.currentValue
        // 事件派发（向上）
        this.dispatch(config.prefix + '-form-item', eventType, _value)
        // 事件广播 （向下）
        this.broadcast(config.prefix + '-form-item', eventType, _value)
      }
    },
    // 分发校验事件
    dispatchValidateEvent: function (value) {
      if (this.isFormItem && this.doValidate) {
        this.$nextTick(() => {
          const _value = (typeof value !== 'undefined') ? value : this.currentValue
          // 事件派发（向上）
          this.dispatch(config.prefix + '-form-item', 'validate', _value)
          // 事件广播 （向下）
          this.broadcast(config.prefix + '-form-item', 'validate', _value)
        })
      }
    },
    handleItemInput (value) { // 处理从form-item触发的值改变
      this.$emit('input', value)
      this.$emit('radioGroupChange', value)
      this.$emit('checkboxChange', value)
      this.$emit('checkboxGroupChange', value)
    },
    validate (callback) {
      this.$nextTick(() => {
        this.$children[0].validate(callback)
      })
    }
  },
  created () {
    this.adjustIsFormItem()
    /*
     * var _this = this;
     *  如果是下拉框
     * if (this.$options.name == config.prefix + '-select') {
     *     // 如果是多选
     *     if (this.multiple) {
     *         // Object.defineProperty() 进行数据监听
     *         Object.defineProperty(this, 'initialValue', {
     *             configurable: false, // 是否可以修改属性
     *             enumerable: false, // 是否可以枚举。 for-in ，object.keys()
     *             writable: false, //  是否可以修改值,默认不可修改
     *             value: this.selectedMultiple
     *         });
     *         // 单选
     *     } else {
     *         // Object.defineProperty() 进行数据监听
     *         Object.defineProperty(this, 'initialValue', {
     *             configurable: false, // 是否可以修改属性
     *             enumerable: false, // 是否可以枚举。 for-in ，object.keys()
     *             writable: false, //  是否可以修改值,默认不可修改
     *             value: this.selectedSingle
     *         });
     *     }
     *
     * } else {
     *     // 初始化值,不允许更改
     *     // Object.defineProperty() 进行数据监听
     *     Object.defineProperty(this, 'initialValue', {
     *         configurable: false, // 是否可以修改属性
     *         enumerable: false, // 是否可以枚举。 for-in ，object.keys()
     *         writable: false, //  是否可以修改值,默认不可修改
     *         value: this.value
     *     });
     * }
     * 绑定事件 blur and change
     * this.$on('initialValue', this.handleInitialValue);
     * 触发初始化事件
     */
    if (!this.isFormItem) {
      return // 非formItem不发送事件
    }
    this.$nextTick(() => {
      //  如果是下拉框
      if (this.$options.name === config.prefix + '-select') {
        //  分发事件
        this.dispatchEvent('initValue', this.value)
      } else if (this.$options.name === config.prefix + '-date-picker') { // 解决日期绑定的是时间戳情况自定义校验不好用问题, 因为是number, 自定义校验需要指定为string
        this.dispatchEvent('initValue', this.$refs.input.value)
      } else if (this.$options.name === config.prefix + '-select-tree' || this.$options.name === config.prefix + '-organ-tree') {
        if (this.multiple) {
          this.dispatchEvent('initValue', this.checkedIds)
        } else {
          this.dispatchEvent('initValue', this.activeId)
        }
      } else {
        this.dispatchEvent('initValue', this.currentValue)
      }
    })
  }
}
